package query;

import global.Minibase;
import global.RID;
import global.SearchKey;
import heap.HeapFile;
import index.HashIndex;
import parser.AST_CreateIndex;
import relop.FileScan;
import relop.Schema;
import relop.Tuple;

/**
 * Execution plan for creating indexes.
 */
class CreateIndex implements Plan {

	/** Name of the index to create. */
	protected String indexFileName;

	/** Name of table on which we shoud index. */
	protected String tableName;

	/** Name of table on which we shoud index. */
	protected String columnName;

	protected Catalog catlog;
	protected Schema schema;
	/**
	 * Optimizes the plan, given the parsed query.
	 * 
	 * @throws QueryException
	 *             if index already exists or table/column invalid
	 */
	public CreateIndex(AST_CreateIndex tree) throws QueryException {

		catlog = new Catalog(true); // TODO check true/false

		indexFileName = tree.getFileName();
		QueryCheck.fileNotExists(indexFileName);
		
		// TODO is index already exists same as filename already exists
//		QueryCheck.indexExists(indexFileName);
		// get and validate the requested schema
		tableName = tree.getIxTable();
		columnName = tree.getIxColumn();
		
		//TODO do we need to check if there is already an index on the table/column and disallow it?
		schema = catlog.getSchema(tableName);
		if (schema == null)
			throw new QueryException("Invalid table Name");
		QueryCheck.tableExists(tableName);
		QueryCheck.columnExists(schema, columnName);

		// } catch (ParseException exc) {
		// throw new QueryException(exc.getMessage());
		// }
	} // public CreateIndex(AST_CreateIndex tree) throws QueryException

	/**
	 * Executes the plan and prints applicable output.
	 */
	public void execute() {
		//TODO is it always hash idx
		HashIndex hashIdx = new HashIndex(indexFileName);
		HeapFile tableFile = new HeapFile(tableName);
		FileScan fileScan = new FileScan(schema, tableFile);
		while (fileScan.hasNext()) {
			Tuple nextTuple = fileScan.getNext();
			Object colValue = nextTuple.getField(columnName);
			RID newRID = new RID();
			hashIdx.insertEntry(new SearchKey(colValue), newRID);
		}
		
		//TODO close before or after systemcat.create
		fileScan.close();
		
		// add to catalog
		Minibase.SystemCatalog.createIndex(indexFileName, tableName, columnName);
		
		// print the output message
		System.out.println("Index created.");

	} // public void execute()

} // class CreateIndex implements Plan
